package gamehistory.utils.computation;

import java.util.HashMap;
import edu.neu.ccs.evergreen.ir.Relation;

/**
 * A Factory class to manufacture polynomials for Relations.
 * @author Team Nerdicide - Brent Kersanske and Brad Lajoie
 * @since 10/1/2009
 * @version Last modified 10/1/2009
 */
public class RelationPolynomialFactory {
	
	// The map of q values to Polynomials
	private static final HashMap<Integer, Polynomial> qValuePolynomialMap = new HashMap<Integer, Polynomial> ();
	
	static {
		/* Event 000 correlates to probability (1 - p)^3 */
		qValuePolynomialMap.put(0, CommonPolynomials.oneMinusPPowerThree);
		/* Events 001, 010, and 100 correlate to probability (1 - p)^2 * p */
		qValuePolynomialMap.put(1, CommonPolynomials.oneMinusPPowerTwoTimesP);
		/* Events 011, 101, and 110 correlate to probability (1 - p) * p ^2 */
		qValuePolynomialMap.put(2, CommonPolynomials.oneMinusPTimesPPowerTwo);
		/* Event 111 correlates to probability p^3 */
		qValuePolynomialMap.put(3, CommonPolynomials.pPowerThree);
	}
	
	/**
	 * Retrieves a polynomial for the given relation.
	 * @param relation The relation to retrieve a polynomial for.
	 * @return The polynomial corresponding to the given relation.
	 */
	public static Polynomial retrievePolynomialForRelation(Relation relation) {		
		Polynomial composedPolynomial = retrievePolynomialsForQValue(0, relation.q(0));
		composedPolynomial            = composedPolynomial.add(retrievePolynomialsForQValue(1, relation.q(1)));
		composedPolynomial            = composedPolynomial.add(retrievePolynomialsForQValue(2, relation.q(2)));
		composedPolynomial            = composedPolynomial.add(retrievePolynomialsForQValue(3, relation.q(3)));	
		return composedPolynomial;		
	}

	/**
	 * Retrieves a polynomial for a given value of q and number of q clauses. 
	 * Continually adds the polynomial to the mapped polynomial until all the q clauses 
	 * for that q value are represented.
	 * @param qValue The q value that maps to a polynomial.
	 * @param numberOfQClauses The number of clauses satisfying that q value.
	 * @return The constructed polynomial for the given value of q, and number of q clauses.
	 */
	private static Polynomial retrievePolynomialsForQValue(int qValue, int numberOfQClauses) {
		Polynomial polynomial = new Polynomial(0, 0);
		while(numberOfQClauses > 0) {
			polynomial       = polynomial.add(qValuePolynomialMap.get(qValue));
			numberOfQClauses = numberOfQClauses - 1;
		}
		return polynomial;
	}

	
}
